import { z } from "zod";

// 1、简单使用 schema 验证数据​ 
// 定义一个 Zod schema​ 
const CarSchema = z.object({
    plateNumber: z.string(),
    type: z.number(),
    status: z.string(),
});
const carData = {
    plateNumber: "川A12345",
    type: 1,
    status: "正常",
};
try {
    CarSchema.parse(carData); // 验证通过​ 
    console.log("验证通过");
} catch (e) {
    console.error("验证失败", e.errors);
}

// 2、自动生成 TypeScript 类型​ 
type Car = z.infer<typeof CarSchema>;
const carData2: Car = {
    plateNumber: "川A66666",
    type: 1,
    status: "正常",
};
try {
    CarSchema.parse(carData2); // 验证通过​ 
    console.log("验证通过");
} catch (e) {
    console.error("验证失败", e.errors);
}

// 3、嵌套对象和数组
// 定义一个嵌套的 Zod schema​ 
const AddressSchema = z.object({
    zipCode: z.string().length(5),
});

const OrgSchema = z.object({
    orgName: z.string(),
    registerYear: z.number().positive(),
    email: z.string().email(),
    address: AddressSchema,
    range: z.array(z.string()),
});
type Org = z.infer<typeof OrgSchema>;
const orgData: Org = {
    orgName: "Jane Doe",
    registerYear: 25,
    email: "jane.doe@example.com",
    address: {
        // street: "天府大道桂溪街道", // 报错：Object literal may only specify known properties, and 'street' does not exist in type '{ zipCode: string; }'.
        // city: "四川成都", // 报错：Object literal may only specify known properties, and 'city' does not exist in type '{ zipCode: string; }'.
        zipCode: "12345",
    },
    range: ["计算机服务", "宠物食品"],
};

try {
    OrgSchema.parse(orgData); // 验证通过​ 
    console.log("验证通过");
} catch (e) {
    console.error("验证失败", e.errors);
}

// 4、使用 Refine 进行自定义验证​
// Zod 允许你添加自定义的验证逻辑，以处理更复杂的验证需求。​
const PasswordSchema = z.string()
    .min(8, "密码不能少于8位")
    .refine((password) => /[A-Z]/.test(password), {
        message: "密码必须包含至少一个大写字母",
    })
    .refine((password) => /[a-z]/.test(password), {
        message: "密码必须包含至少一个小写字母",
    })
    .refine((password) => /[0-9]/.test(password), {
        message: "密码必须包含至少一个数字",
    });

const UserSchema = z.object({
    username: z.string(),
    password: PasswordSchema,
});

type User = z.infer<typeof UserSchema>;
const userData: User = {
    username: "小明",
    password: "Pwd2333",
};

try {
    UserSchema.parse(userData); // 验证通过​ 
    console.log("验证通过");
} catch (e) {
    console.error("验证失败", e.errors);
}